import queue
from concurrent.futures import ThreadPoolExecutor
from logging import Handler
from queue import Queue
from threading import Thread


class LogSRecord(object):
    group = None
    level = None
    msg = None

    def __init__(self, group, level, msg):
        self.group = group
        self.level = level
        self.msg = msg

    def __str__(self):
        return f'[{self.group}] {self.level} - {self.msg}'

    def __repr__(self):
        return self.__str__()


class DbHandler(Handler):
    """
    日志持久化至数据库
    """
    group = None
    queue: Queue = None

    def __init__(self, group=None):
        super().__init__()
        self.group = group
        # 缓存日志
        self.queue: Queue = Queue(5000)
        # init
        self.store_thread = AsyncLogStoreThread(self.queue)

    def emit(self, record):
        try:
            msg = self.format(record)
            self.queue.put_nowait((LogSRecord(self.group, record.levelno, msg)))
        except Exception:
            self.handleError(record)


class AsyncLogStoreThread(Thread):
    """
    异步存储
    """

    def __init__(self, queue):
        Thread.__init__(self)
        self.queue: Queue = queue
        self.daemon = True
        self.start()

    def run(self):
        with ThreadPoolExecutor(max_workers=2) as executor:
            while True:
                try:
                    record: LogSRecord = self.queue.get(block=True, timeout=1)
                    executor.submit(self.store_log, record)
                except queue.Empty:
                    pass  # 队列为空时，继续等待

    def store_log(self, msg: LogSRecord):
        """
        TODO: 日志持久化至数据库
        """
        print('[DB-LOG] ' + msg.__str__())
